#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time    : 2024/9/25 16:07
# @Author  : Tom_zc
# @FileName: pipeline_helper.py
# @Software: PyCharm
import logging
from huaweicloudsdkcloudpipeline.v2.region.cloudpipeline_region import CloudPipelineRegion
from huaweicloudsdkcodeartspipeline.v2 import CodeArtsPipelineClient, ShowPipelineRunDetailRequest, \
    ShowPipelineLogRequest, LogQuery, ShowStepOutputsRequest
from huaweicloudsdkcodeartspipeline.v2.region.codeartspipeline_region import CodeArtsPipelineRegion
from huaweicloudsdkcore.auth.credentials import BasicCredentials
from huaweicloudsdkcodeartsbuild.v3.region.codeartsbuild_region import CodeArtsBuildRegion
from huaweicloudsdkcodeartsbuild.v3 import *
from huaweicloudsdkcore.exceptions import exceptions

logging.basicConfig(level=logging.INFO,
                    format="%(asctime)s  %(levelname)s:%(message)s")


class PipeLineHelper:
    def __init__(self, ak, sk):
        self._credentials = BasicCredentials(ak, sk)

    def get_pipeline_run_detail(self, project_id, pipeline_id, pipeline_run_id):
        try:
            client = CodeArtsPipelineClient.new_builder() \
                .with_credentials(self._credentials) \
                .with_region(CodeArtsPipelineRegion.value_of("cn-north-4")) \
                .build()
            request = ShowPipelineRunDetailRequest()
            request.pipeline_run_id = pipeline_run_id
            request.project_id = project_id
            request.pipeline_id = pipeline_id
            response = client.show_pipeline_run_detail(request)
            return response.to_json_object()
        except exceptions.ClientRequestException as e:
            logging.info("[get_pipeline_run_detail] {}/{}/{}/{}".format(e.status_code,
                                                                        e.request_id,
                                                                        e.error_code,
                                                                        e.error_msg))
            raise Exception("get_pipeline_run_detail failed")

    def get_pipeline_log(self, project_id, pipeline_id, pipeline_run_id, job_run_id, step_run_id):
        client = CodeArtsPipelineClient.new_builder() \
            .with_credentials(self._credentials) \
            .with_region(CloudPipelineRegion.value_of("cn-north-4")) \
            .build()
        try:
            start_offset = 0
            log_content = str()
            while True:
                request = ShowPipelineLogRequest()
                request.project_id = project_id
                request.pipeline_id = pipeline_id
                request.pipeline_run_id = pipeline_run_id
                request.job_run_id = job_run_id
                request.step_run_id = step_run_id
                request.body = LogQuery(
                    start_offset=start_offset,
                    sort="asc",
                    limit=1000
                )
                response = client.show_pipeline_log(request)
                log_content += response.log
                if not response.has_more:
                    break
                start_offset = response.end_offset
            return log_content
        except exceptions.ClientRequestException as e:
            logging.info("[get_pipeline_log] {}/{}/{}/{}".format(e.status_code,
                                                                 e.request_id,
                                                                 e.error_code,
                                                                 e.error_msg))
            raise Exception("get_pipeline_log failed")

    def get_build_number(self, job_id, record_id):
        client = CodeArtsBuildClient.new_builder() \
            .with_credentials(self._credentials) \
            .with_region(CodeArtsBuildRegion.value_of("cn-north-4")) \
            .build()

        try:
            request = ShowListHistoryRequest()
            request.job_id = job_id
            request.interval = 5
            request.offset = 0
            request.limit = 100
            response = client.show_list_history(request)
            for record in response.history_records:
                if record.job_id == job_id and record.record_id == record_id:
                    return record.build_number
            raise Exception("not found the build number in {}/{}".format(job_id, record_id))
        except exceptions.ClientRequestException as e:
            logging.info("[get_build_list_history] {}/{}/{}/{}".format(e.status_code,
                                                                       e.request_id,
                                                                       e.error_code,
                                                                       e.error_msg))
            raise Exception("get_build_list_history failed")

    def get_build_record_id(self, job_id, build_number):
        client = CodeArtsBuildClient.new_builder() \
            .with_credentials(self._credentials) \
            .with_region(CodeArtsBuildRegion.value_of("cn-north-4")) \
            .build()

        try:
            request = ShowRecordDetailRequest()
            request.job_id = job_id
            request.build_no = build_number
            response = client.show_record_detail(request)
            return response.result.build_record_id
        except exceptions.ClientRequestException as e:
            logging.info("[get_build_record_id] {}/{}/{}/{}".format(e.status_code,
                                                                    e.request_id,
                                                                    e.error_code,
                                                                    e.error_msg))
            raise Exception("get_build_record_id failed")

    # noinspection PyProtectedMember
    def download_build_log(self, record_number):
        client = CodeArtsBuildClient.new_builder() \
            .with_credentials(self._credentials) \
            .with_region(CodeArtsBuildRegion.value_of("cn-north-4")) \
            .build()

        try:
            request = DownloadBuildLogRequest()
            request.record_id = record_number
            response = client.download_build_log(request)
            return response._stream.content.decode()
        except exceptions.ClientRequestException as e:
            logging.info("[download_build_log] {}/{}/{}/{}".format(e.status_code,
                                                                   e.request_id,
                                                                   e.error_code,
                                                                   e.error_msg))
            raise Exception("download_build_log failed")

    def show_step_output(self, project_id, pipeline_id, pipeline_run_id, step_run_ids):
        client = CodeArtsPipelineClient.new_builder() \
            .with_credentials(self._credentials) \
            .with_region(CodeArtsPipelineRegion.value_of("cn-north-4")) \
            .build()

        try:
            request = ShowStepOutputsRequest()
            request.project_id = project_id
            request.pipeline_id = pipeline_id
            request.pipeline_run_id = pipeline_run_id
            request.step_run_ids = step_run_ids
            response = client.show_step_outputs(request)
            return response.to_json_object()
        except exceptions.ClientRequestException as e:
            logging.info("[show_step_output] {}/{}/{}/{}".format(e.status_code,
                                                                 e.request_id,
                                                                 e.error_code,
                                                                 e.error_msg))
            raise Exception("show_step_output failed")
